<?php

namespace app\admin\controller\examine;

use app\admin\model\kuerp\ExpenseInfo;
use app\admin\model\kuerp\Prefix;
use addons\kuerp\model\ExamineRecord;
use addons\kuerp\model\Flows;
use addons\kuerp\model\Message;
use app\admin\model\Admin;
use app\common\controller\Backend;
use think\Db;
use Exception;
use think\exception\PDOException;
use think\exception\ValidateException;
/**
 * 报销管理
 *
 * @icon fa fa-circle-o
 */
class Expense extends Backend
{

    /**
     * Expense模型对象
     * @var \app\admin\model\kuerp\Expense
     */
    protected $model = null;
    protected $flows = [];
    protected $examine_index = 0;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\kuerp\Expense;

        $this->assignconfig('admin_id',$this->auth->id);
        //获取审批流程
        $flows = Db::name('flows')->where('relation_type', 'expense')->where('status', 1)->find();
        if (empty($flows)){
            $this->error('请先设置并启用报销审批流程');
        }
        $flows['flow_items'] = json_decode($flows['flow_items'], true);
        //判断流程中是否有当前用户审核
        $examine_index = 0;
        foreach ($flows['flow_items'] as $key => $value) {
            if (in_array($this->auth->id, explode(',',$value['admin_id'])) ) {
                $examine_index = $key + 1;
                // break;
            }
        }
        if ($examine_index == 0 && !$this->auth->isSuperAdmin()) {
            $this->error('您不在审批流程中');
        }
        $this->examine_index = $examine_index;
        $this->flows = $flows;
    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = false;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        $adminids = $this->auth->adminids;
        //系统设置特定审核人员
        $config_examine_admins = config('site.examine_admins');
        if (!empty($config_examine_admins[$this->auth->id])) {
            //获取对应销售id
            $adminids = array_merge($adminids,explode(',',$config_examine_admins[$this->auth->id]));
        }
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            $wheres = [
                'admin_id' => ['in', $adminids]
            ];
            $filter = json_decode($this->request->get("filter", ''), true);
            $op = json_decode($this->request->get("op", '','trim'), true);
            if (isset($filter['income_month'])) {
                // 自定义处理
                $income_month = $filter['income_month'];
                // 处理完可以去掉也可以覆盖重构
                unset($filter['income_month'],$op['income_month']);
                $wheres['income_month'] = strtotime($income_month);
            }
            if (isset($filter['check_status'])) {
                // 自定义处理
                $check_status = $filter['check_status'];
                // 处理完可以去掉也可以覆盖重构
                unset($filter['check_status'],$op['check_status']);
            } else if ($this->request->get('check_status') !== null){
                $check_status = $this->request->get('check_status');
            }
            $check_status = isset($check_status) ? $check_status : 0;
            if ($check_status == 1) {
                $wheres['id'] = ['exp', Db::raw(' > 0 and FIND_IN_SET('.$this->auth->id.',check_history_uids)')];
                // $wheres['check_status'] = ['exp', Db::raw('=2 OR (check_status="1" AND (check_step_sort >= '.($this->examine_index ? : 1).' OR FIND_IN_SET('.$this->auth->id.',`check_uids`)))')];
            }else{
                $wheres['check_status'] = '1';
                $wheres['check_step_sort'] = $this->examine_index - 1;//不可跨级
                // $ruleWhere['check_uids'] = ['not like', $this->auth->id];
                $wheres['check_uids'] = ['exp', Db::raw('="" OR FIND_IN_SET('.$this->auth->id.',check_uids) = 0')];
            } 
            $this->request->get(['filter'=>json_encode($filter,true)]);
            $this->request->get(['op'=>json_encode($op,true)]);
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                    ->where($where)
                    ->where($wheres)
                    ->order($sort, $order)
                    ->paginate($limit);

            foreach ($list as $row) {
                $row->visible(['id','expense_code','cost','income_month','start_time','subject_matter','end_time','admin_id','did','pay_status','remark','createtime','updatetime','check_status']);
                
            }
            if ($list->items()) {
                // $admins = array_column($list->items(), 'admin_id');
                // $check_last_uids = array_column($list->items(), 'check_last_uid');
                // $adminids = array_values(array_unique(array_merge($admins, $check_last_uids)));
                // $adminlist = Db::name('admin')->where('id', 'in', $adminids)->column('nickname,avatar', 'id');
                foreach ($list as $key => $value) {
                    // $list[$key]['admin'] = $adminlist[$value['admin_id']] ?? [];
                    // $list[$key]['last_checkadmin'] = $adminlist[$value['check_last_uid']] ?? [];
                    if ($check_status == 0) {
                        $list[$key]['check_status'] = $value['check_status'] == 1 ? 0 : $value['check_status'];
                    } else {
                        //获取最后一条审核日志
                        $last_status = Db::name('examine_log')->where(['relation_type' => 'expense', 'relation_id' => $value['id'], 'admin_id' => $this->auth->id])->order('id desc')->value('examine_status');
                        $list[$key]['check_status'] = $last_status == 0 ? 3 : 2;
                    }
                    
                }
            }
            $total_cost = $this->model->where($where)->where($wheres)->sum('cost');
            $result = array("total" => $list->total(), "rows" => $list->items(),"extend" => ["total_cost"=>$total_cost]);

            return json($result);
        }
        //获取报销人列表 搜索
        // $adminids = $this->auth->adminids;
        $adminlist = Db::name("admin")->where("id", 'in', $adminids)->column("nickname","id");
        $this->assignconfig("adminlist", $adminlist);
        return $this->view->fetch();
    }


    public function detail($ids)
    {
        $row = $this->model->getInfo($ids);
        $row['admin'] = Admin::where('id', $row['admin_id'])->field('nickname,avatar')->find();
        $this->view->assign('row', $row);
        //获取审核信息
        // $logWhere = [
        //     'relation_type' => 'expense',
        //     'relation_id' => $ids,
        // ];
        // $logList = Db::name('examine_log')->where($logWhere)->order('id desc')->select();
        // if (!empty($logList)) {
        //     $admin_ids = array_column($logList,'admin_id');
        //     $admin_data = Db::name('admin')->where(['id'=>['in',$admin_ids]])->column('nickname,username,avatar','id');
        //     foreach ($logList as $log_k=>$log_v) {
        //         $logList[$log_k]['admin_name'] = $admin_data[$log_v['admin_id']]['nickname'] ?? $admin_data[$log_v['admin_id']]['username'] ?? '';
        //         $logList[$log_k]['admin_avatar'] = $admin_data[$log_v['admin_id']]['avatar'] ?? '';
        //         $logList[$log_k]['createtime'] = date('Y/m/d H:i', $log_v['createtime']);
        //     }
        // }

        // $this->assign('log_list',$logList);
        // $this->assign('examine_record',ExamineRecord::getList(ExamineRecord::CONTRACT_TYPE,$ids));
        $flows = Flows::getstepdetail(Flows::EXPENSE_STATUS, $ids);
        $this->assign('stepList',$flows['stepList']);

        $infoModel = new ExpenseInfo();
        //明细表格字段
        $table = $infoModel->getQuery()->getTable();
        $database = \think\Config::get('database.database');
        $fieldArr = [];
        $list = db()->query("SELECT COLUMN_NAME as name,COLUMN_COMMENT as comment,DATA_TYPE as type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
        //排除字段
        $excludeFields = ['id','expense_id','admin_id','createtime','updatetime'];
        foreach ($list as $k => $v) {
            if (in_array($v['name'], $excludeFields)) {
                continue;
            }
            $fieldArr[] = $v;
        }
        $this->view->assign('fields', $fieldArr);
        $infoList = $infoModel->getInfo($ids);
        if ($infoList) {
            //infoList最后加上各个字段合计值
            $sumRow = [];
            foreach ($fieldArr as $field) {
                if($field['type'] != 'varchar') {
                    $sumRow[$field['name']] = round(array_sum(array_column($infoList, $field['name'])),2);
                } else {
                    $sumRow[$field['name']] = $field['name'] == 'subject_matter' ? '合计' : '';
                }
            }
            $sumRow['expense_time_text'] = '';
            $infoList[] = $sumRow;
        }
        $this->assign('info_list',$infoList);
        $this->assign('ids',$ids);
        //判断是否可审核
        $can_examine = false;
        if ($this->examine_index > 0 && $row['check_status'] == 1 && $row['check_step_sort'] == ($this->examine_index - 1) ) {
            $can_examine = true;
        }
        $this->view->assign('can_examine', $can_examine);
        return $this->view->fetch();
    }

    public function examine()
    {
        $id = $this->request->post("id");//1通过 0拒绝
        $status = $this->request->post("status");//1通过 0拒绝
        $remark = $this->request->post("remark", '');
        
        $row = $this->model->get($id);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (!$status) {
            if (empty($remark)) {
                $this->error('请填写审批不通过原因');
            }
        }
        $log = [
            'flows_id' => $this->flows['id'],
            'relation_type' => 'expense',
            'relation_id' => $row['id'],
            'cur_index' => $this->examine_index,
            'admin_id' => $this->auth->id,
            'examine_status' => $status,
            'remark' => $remark,
            'createtime' => time(),
        ];
        $update = [
            'check_status' => $status ? $row['check_status'] : 3,
            'check_remark' => $remark,
            'check_last_uid' => $this->auth->id,
            'check_step_sort' => $status ? $this->examine_index : 0,//审核拒绝回到最开始
            'check_uids' => '',//
        ];
        //判断这一级审批类型 stafftype=1 任意一人审批； stafftype=2 多人会签
        $flow_item = $this->flows['flow_items'][$this->examine_index - 1] ?? [];
        if ($status && !empty($flow_item['stafftype']) && $flow_item['stafftype'] == 2) {
            //查看其他人是否已审核
            if ($flow_item['admin_id'] != (string)$this->auth->id) {
                //这一级需要审核的人员
                $admin_ids = explode(',', $flow_item['admin_id']);
                //这一级已审核的人员
                $sale_adminids = $row['check_step_sort'] == $this->examine_index && $row['check_uids'] ? explode(',', $row['check_uids']) : [];
                $sale_adminids[] = $this->auth->id;
                $sale_adminids = array_intersect($admin_ids,$sale_adminids);
                if (count($sale_adminids) < count($admin_ids)) {
                    unset($update['check_step_sort']); 
                    $update['check_uids'] = $row['check_uids'] ? $row['check_uids'] . ',' . $this->auth->id : $this->auth->id;
                }
            }
        }
        //如果申请人本身在审批人员中，判断退回到该申请人所在审批步骤
        if (!$status) {
            $examine_index = 0;
            foreach ($this->flows['flow_items'] as $key => $value) {
                if (in_array($row['admin_id'], explode(',',$value['admin_id'])) ) {
                    $examine_index = $key + 1;
                    // break;
                }
            }
            $update['check_step_sort'] = $examine_index;
        }
        $update['check_history_uids'] = $row['check_history_uids'] ? $row['check_history_uids'] . ',' . $this->auth->id : $this->auth->id;
        $update['check_history_uids'] = $status ? $update['check_history_uids'] : '';//拒绝清空已审批人
        //最后一级审批
        if ($status && !empty($update['check_step_sort']) && $this->examine_index == count($this->flows['flow_items'])){
            $update['check_status'] = 2;
            $update['check_time'] = time();
        }
        
        $result = false;
        Db::startTrans();
        try {
            $logid = Db::name('examine_log')->insertGetId($log);
            
            $result = $this->model->where(['id'=>['in',$id]])->update($update);
            if ($message = Message::where(['relation_type' => 'examine', 'relation_id' => $row['id'], 'to_staff_id' => $this->auth->id])->find()) {
                Message::where(['id' => $message['id']])->update(['status' => 1, 'read_time' => time()]);
            }
            if ($status) {
                $flow = Flows::getFlowByTypes(Flows::EXPENSE_STATUS);
                //给下一审核人发送通知
                $check_staff_ids = $update['check_history_uids'];
                $result = Flows::sendStepRecord($flow, Flows::EXPENSE_STATUS, $row['id'], $check_staff_ids, $update['check_step_sort'] ?? $row['check_step_sort']);
                //完成审批发送
                if ($update['check_status'] == 2) {
                    Message::addMessage(Message::EXAMINE_ADOPT_TYPE, $logid, $row['admin_id'], $this->auth->id);
                }
            } else {
                Message::addMessage(Message::EXAMINE_REFUSE_TYPE, $logid, $row['admin_id'], $this->auth->id, '');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result !== false) {
            $this->success();
        } else {
            $this->error('审核失败');
        }
    }
}

